﻿using System.Linq.Expressions;
using SqlSugar;

namespace IServices;

public interface IBaseService<T>
    where T : class
{
    #region 查询

    Task<T> GetByIdAsync(dynamic id);
    T GetById(dynamic id);

    /// <summary>
    ///     查询单个
    /// </summary>
    /// <param name="predicate"></param>
    /// <returns></returns>
    T GetSingle(Expression<Func<T, bool>> predicate);
    Task<T> GetSingleAsync(Expression<Func<T, bool>> predicate);

    /// <summary>
    ///     查询所有
    /// </summary>
    /// <returns></returns>
    Task<IEnumerable<T>> GetListAsync();
    IEnumerable<T> GetList();

    /// <summary>
    ///     查询符合条件的
    /// </summary>
    /// <param name="predicate"></param>
    /// <returns></returns>
    Task<IEnumerable<T>> GetListAsync(Expression<Func<T, bool>> predicate);
    IEnumerable<T> GetList(Expression<Func<T, bool>> predicate);

    /// <summary>
    ///     查询符合条件的，可以选择查询那些列
    /// </summary>
    /// <param name="predicate"></param>
    /// <param name="includes"></param>
    /// <returns></returns>
    Task<IEnumerable<T>> GetListAsync(Expression<Func<T, bool>> predicate, dynamic selectColumns);

    /// <summary>
    ///     分页查询
    /// </summary>
    /// <returns></returns>
    Task<IEnumerable<T>> GetPageListAsync(
        Expression<Func<T, bool>> expression,
        int pageIndex,
        int pageSize
    );
    IEnumerable<T> GetPageList(Expression<Func<T, bool>> expression, int pageIndex, int pageSize);

    /// <summary>
    ///     分页查询 并排序
    /// </summary>
    /// <returns></returns>
    Task<IEnumerable<T>> GetPageListAsync(
        Expression<Func<T, bool>> expression,
        int pageIndex,
        int pageSize,
        Expression<Func<T, object>> orderByExpression,
        OrderByType orderByType = OrderByType.Asc
    );

    IEnumerable<T> GetPageList(
        Expression<Func<T, bool>> expression,
        int pageIndex,
        int pageSize,
        Expression<Func<T, object>> orderByExpression,
        OrderByType orderByType = OrderByType.Asc
    );

    #endregion 查询

    #region 新增

    /// <summary>
    ///     新增
    /// </summary>
    /// <param name="entity"></param>
    /// <returns></returns>
    Task<bool> AddAsync(T entity);

    bool Add(T entity);

    /// <summary>
    ///     批量新增
    /// </summary>
    /// <param name="entities"></param>
    /// <returns></returns>
    Task<bool> AddRangeAsync(List<T> entities);
    bool AddRange(List<T> entities);

    /// <summary>
    ///     插入返回自增
    /// </summary>
    /// <param name="entity"></param>
    /// <returns></returns>
    Task<object> InsertReturnIdentityAsync(T entity);

    object InsertReturnIdentity(T entity);

    #endregion 新增

    #region 修改

    /// <summary>
    ///     更新
    /// </summary>
    /// <param name="entity"></param>
    /// <returns></returns>
    bool Update(T entity);

    Task<bool> UpdateAsync(T entity);

    /// <summary>
    ///     批量更新
    /// </summary>
    /// <param name="entities"></param>
    /// <returns></returns>
    Task<bool> UpdateRangeAsync(List<T> entities);
    bool UpdateRange(List<T> entities);

    #endregion 修改

    #region 删除

    /// <summary>
    ///     实体删除 需要有主键
    /// </summary>
    /// <param name=""></param>
    /// <returns></returns>
    bool Delete(T entity);
    Task<bool> DeleteAsync(T entity);

    /// <summary>
    ///     实体列表删除 需要有主键
    /// </summary>
    /// <param name="entities"></param>
    /// <returns></returns>
    Task<bool> DeleteAsync(List<T> entities);
    bool Delete(List<T> entities);

    /// <summary>
    ///     根据主键删除
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    Task<bool> DeleteByIdAsync(object id);
    bool DeleteById(object id);

    /// <summary>
    ///     根据ids 列表删除
    /// </summary>
    /// <param name="ids"></param>
    /// <returns></returns>
    Task<bool> DeleteByIdsAsync(dynamic[] ids);
    bool DeleteByIds(dynamic[] ids);

    /// <summary>
    ///     根据条件删除
    /// </summary>
    /// <param name="predicate"></param>
    /// <returns></returns>
    Task<bool> DeleteAsync(Expression<Func<T, bool>> predicate);
    bool Delete(Expression<Func<T, bool>> predicate);

    #endregion 删除
}
